/**
 * Bone.cpp
 * Coyright (c) 2009 Xiaofeng Gu. All Rights Reserved.
 * Author : Xiaofeng Gu
 *
 * Creation Data : 2009/06/11
 */

#include "stdafx.h"
#include "Bone.h"
#include <math.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif



///////////////////////////////////////////////////////
/// class CBone
///////////////////////////////////////////////////////
CBone::CBone()
{
	m_FixedJoint.SetType(CJoint::eFixed);
	m_MovingJoint.SetType(CJoint::eMoving);
}

CBone::~CBone()
{
}

bool CBone::Rotate(CVec& Ref, double dAngle)
{
	CVec oBoneVec = ((*this)[1] - (*this)[0]);

	// refresh 0, 1 joints
	oBoneVec.RotateBy(Ref, dAngle);
	(*this)[1] = (*this)[0] + oBoneVec;

	// refresh normal
	m_oNormal.RotateBy(Ref, dAngle);

	return true;
}

bool CBone::Screw(double dAngle)
{
	CVec Ref = ((*this)[1] - (*this)[0]);

	// refresh normal
	m_oNormal.RotateBy(Ref, dAngle);

	return true;
}

bool CBone::Rotate(CJoint& oJoint, CVec& Ref, double dAngle)
{
	CVec V1 = (*this)[0] - oJoint;
	V1.RotateBy(Ref, dAngle);
	(*this)[0] = oJoint + V1;

	CVec V2 = (*this)[1] - oJoint;
	V2.RotateBy(Ref, dAngle);
	(*this)[1] = oJoint + V2;

	m_oNormal.RotateBy(Ref, dAngle);

	return true;
}

bool CBone::Move(CVec& Ref)
{
	(*this)[0] = (*this)[0] + Ref;
	(*this)[1] = (*this)[1] + Ref;

	return true;
}

void CBone::operator=(const CBone& bone)
{
	m_FixedJoint = bone.m_FixedJoint;
	m_MovingJoint = bone.m_MovingJoint;
	m_oNormal = bone.m_oNormal;
}

CVec CBone::Direction()
{
	return m_MovingJoint - m_FixedJoint;
}

bool CBone::OnRead(CXMLParser* pParser)
{
	double x, y, z;
	if (pParser->FindChildNode(NODE_BONE))
	{
		m_FixedJoint.OnRead(pParser);
		m_MovingJoint.OnRead(pParser);

		if (pParser->FindChildNode(NODE_NORMAL))
		{
			if (pParser->FindChildNode(NODE_X, x))
			{
			pParser->FindXMLNode(NODE_Y, y);
			pParser->FindXMLNode(NODE_Z, z);
			m_oNormal = CVec(x, y, z);
			pParser->EndXMLNode();
			}
		pParser->EndXMLNode();
		}
	pParser->EndXMLNode();
	}

	return true;
}

bool CBone::OnWrite(CXMLParser* pParser)
{
	pParser->AddChildNode(NODE_BONE);
		m_FixedJoint.OnWrite(pParser);
		m_MovingJoint.OnWrite(pParser);

		pParser->AddChildNode(NODE_NORMAL);
			pParser->AddChildNode(NODE_X, m_oNormal[0]);
			pParser->AddXMLNode(NODE_Y, m_oNormal[1]);
			pParser->AddXMLNode(NODE_Z, m_oNormal[2]);
			pParser->EndXMLNode();
		pParser->EndXMLNode();
	pParser->EndXMLNode();

	return true;
}